package api

import (
	"ams/dao"
	"ams/global"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"lib/http"
	"lib/id"
	"lib/structs/ams"
	"lib/structs/enum"
	"lib/structs/tables"
	"lib/utils"
	"os"
	"path/filepath"
	"strings"
	"time"
)

var PluginApi = new(pluginApi)

type pluginApi struct {
}

func (a pluginApi) List(c *gin.Context) {
	li, err := dao.PluginDao.FindList()
	if err != nil {
		http.BadWithErr(c, err)
		return
	}
	http.Ok(c, li)
}

// UploadPlugin 上传插件，返回文件MD5，主程序MD5，和下载地址
func (a pluginApi) UploadPlugin(c *gin.Context) {
	f, err := c.FormFile("file")
	if err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	suf := f.Filename[strings.LastIndex(f.Filename, "."):]
	filename := fmt.Sprintf("%d%s", id.GetSnowId(), suf)
	fPath := filepath.Join(global.Conf.AppFolder, "plugin", filename)
	err = c.SaveUploadedFile(f, fPath)
	if err != nil {
		http.BadWithCode(c, enum.ErrorMap.UploadFileErrForIdp)
		return
	}
	// 解压计算文件的MD5
	tempFolder := filepath.Join(global.Conf.AppFolder, "temp", id.GetUuidV4())
	err = utils.Unzip(fPath, tempFolder)
	if err != nil {
		http.BadWithErr(c, err)
		return
	}
	zipMd5 := utils.GetFileMD5(fPath)
	var pluginMd5 string
	err = filepath.Walk(tempFolder, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		pluginMd5 = utils.GetFileMD5(path)
		return nil
	})
	if err != nil {
		http.BadWithErr(c, err)
		return
	}
	http.Ok(c, gin.H{"pluginMd5": pluginMd5, "zipMd5": zipMd5, "filename": filename})
}

func (a pluginApi) Add(c *gin.Context) {
	var in ams.AddPluginDto
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	var m tables.AmsPlugin
	_ = copier.Copy(&m, in)
	m.Id = id.GetSnowId()
	m.CreatedAt = time.Now().Unix()
	err := dao.PluginDao.Create(&m)
	if err != nil {
		http.BadWithErr(c, err)
		return
	}
	http.OK204(c)
}

func (a pluginApi) Update(c *gin.Context) {
	var in ams.UpdatePluginDto
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	var (
		m   tables.AmsPlugin
		err error
	)
	m, err = dao.PluginDao.FindById(in.Id)
	if err != nil {
		http.BadWithErr(c, err)
		return
	}
	_ = copier.Copy(&m, in)
	err = dao.PluginDao.Update(m)
	if err != nil {
		http.BadWithErr(c, err)
		return
	}
	http.OK204(c)
}

func (a pluginApi) Delete(c *gin.Context) {
	in := struct {
		Id int64 `form:"id"`
	}{}
	if err := c.ShouldBindQuery(&in); err != nil {
		http.BadWithParamsError(c, err)
		return
	}
	err := dao.PluginDao.Delete(in.Id)
	if err != nil {
		http.BadWithErr(c, err)
		return
	}
	http.OK204(c)
}
